//
//  CmdData.m
//  SensorTagEX
//
//  Created by sno on 15-1-30.
//  Copyright (c) 2015年 Texas Instruments. All rights reserved.
//

#import "CmdData.h"

#define  CMDHEAD1  0x7F
#define  CMDHEAD2   0x5A
#define  CMDVERSION  0X01
#define  CMD_APP_BYTE  0x04

//连接配对密码
#define  CMD_WORD_T  'T'
//写入RGB的PWM
#define  CMD_WORD_V  'V'
//更改蓝牙设备
#define  CMD_WORD_N  'N'
//更该连接密码
#define  CMD_WORD_P  'P'
//自由跳变颜色
#define  CMD_WORD_F  'F'
//自由渐变颜色
#define  CMD_WORD_S  'S'
//呼吸效果
#define  CMD_WORD_B  'B'
//恢复出厂设置
#define  CMD_WORD_D  'D'
//设置多个颜色值.
#define  CMD_WORD_C  'C'
//设置 开关灯
#define CMD_WORD_O 'O'

//设置渐变跳变的同步命令
#define CMD_WORD_A 'A'

//设置白光
#define CMD_WORD_W 'W'


//接收数据错误
#define  CMD_WORD_RET_E  'E'
//接收数据成功
#define  CMD_WORD_RET_G  'G'
//未定义的命令
#define  CMD_WORD_RET_U  'U'


//反馈状态1
#define  CMD_WORD_RET_01  0x01

//写入RGB的PWM 2组RGB
#define CMD_V_LENGTH  6

//存储当前状
#define CMD_S_LENGTH  0

//更改蓝牙设备
#define CMD_N_LENGTH  12

//更该连接密码
#define CMD_P_LENGTH  6

//恢复出厂设置
#define CMD_D_LENGTH  0

//调试模式   //范围为1-255   ---0为调试状态
#define KEY  0

@implementation CmdData

uint8_t const CRC_TABLE[256]={
    0x00,0x5E,0xBC,0xE2,0x61,0x3F,0xDD,0x83,0xC2,0x9C,0x7E,0x20,0xA3,0xFD,0x1F,0x41,
    0x9D,0xC3,0x21,0x7F,0xFC,0xA2,0x40,0x1E,0x5F,0x01,0xE3,0xBD,0x3E,0x60,0x82,0xDC,
    0x23,0x07,0x9F,0xC1,0x42,0x1C,0xFE,0xA0,0xE1,0xBF,0x5D,0x03,0x80,0xDE,0x3C,0x62,
    0xBE,0xE0,0x02,0x5C,0xDF,0x81,0x63,0x3D,0x7C,0x22,0xC0,0x9E,0x1D,0x43,0xA1,0xFF,
    0x46,0x18,0xFA,0xA4,0x27,0x79,0x9B,0xC5,0x84,0xDA,0x38,0x66,0xE5,0xBB,0x59,0x07,
    0xDB,0x85,0x67,0x39,0xBA,0xE4,0x06,0x58,0x19,0x47,0xA5,0xFB,0x78,0x26,0xC4,0x9A,
    0x65,0x3B,0xD9,0x87,0x04,0x5A,0xB8,0xE6,0xA7,0xF9,0x1B,0x45,0xC6,0x98,0x7A,0x24,
    0xF8,0xA6,0x44,0x1A,0x99,0xC7,0x25,0x7B,0x3A,0x64,0x86,0xD8,0x5B,0x05,0xE7,0xB9,
    0x8C,0xD2,0x30,0x6E,0xED,0xB3,0x51,0x0F,0x4E,0x10,0xF2,0xAC,0x2F,0x71,0x93,0xCD,
    0x11,0x4F,0xAD,0xF3,0x70,0x2E,0xCC,0x92,0xD3,0x8D,0x6F,0x31,0xB2,0xEC,0x0E,0x50,
    0xAF,0xF1,0x13,0x4D,0xCE,0x90,0x72,0x2C,0x6D,0x33,0xD1,0x8F,0x0C,0x52,0xB0,0xEE,
    0x32,0x6C,0x8E,0xD0,0x53,0x0D,0xEF,0xB1,0xF0,0xAE,0x4C,0x12,0x91,0xCF,0x2D,0x73,
    0xCA,0x94,0x76,0x28,0xAB,0xF5,0x17,0x49,0x08,0x56,0xB4,0xEA,0x69,0x37,0xD5,0x8B,
    0x57,0x09,0xEB,0xB5,0x36,0x68,0x8A,0xD4,0x95,0xCB,0x29,0x77,0xF4,0xAA,0x48,0x16,
    0xE9,0xB7,0x55,0x0B,0x88,0xD6,0x34,0x6A,0x2B,0x75,0x97,0xC9,0x4A,0x14,0xF6,0xA8,
    0x74,0x2A,0xC8,0x96,0x15,0x4B,0xA9,0xF7,0xB6,0xE8,0x0A,0x54,0xD7,0x89,0x6B,0x35
};

//+(NSData *)getRGBCmdArray:(int)colorA colorB:(int)colorB retData:(NSData *)retData
+(NSData *)getRGBCmdArray:(int)colorA colorB:(int)colorB
{
    
    uint8_t crc=0;
    int len=CMD_V_LENGTH+8;
    uint8_t *pData=malloc(len);
    
    pData[0]=CMDHEAD1;
    pData[1]=CMDHEAD2;
    pData[2]=0x01;
    pData[3]=CMD_APP_BYTE;
    pData[4]=CMD_WORD_V;
    pData[5]= [self getRandomNumber];
    pData[6]=CMD_V_LENGTH;
    
    uint8_t R,G,B;
    R=(uint8_t)(colorA>>16);
    G=(uint8_t)(colorA>>8);
    B=(uint8_t)(colorA);
    
    pData[7]=R;
    pData[8]=G;
    pData[9]=B;
    
    R=(uint8_t)(colorB>>16);
    G=(uint8_t)(colorB>>8);
    B=(uint8_t)(colorB);
    
    pData[10]=R;
    pData[11]=G;
    pData[12]=B;
    
    [self EncryptCode:pData];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=pData[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    pData[len-1]=crc;
    
     NSData *data=[[NSData alloc]initWithBytes:pData length:len];
     free(pData);
    
     return data;
}

+(void )getRGBCmdArray:(int)colorA colorB:(int)colorB retData:(uint8_t *)retData
{

    uint8_t crc=0;
    int len=CMD_V_LENGTH+8;
    uint8_t *pData=malloc(len);
    
    pData[0]=CMDHEAD1;
    pData[1]=CMDHEAD2;
    pData[2]=0x01;
    pData[3]=CMD_APP_BYTE;
    pData[4]=CMD_WORD_V;
    pData[5]= [self getRandomNumber];
    pData[6]=CMD_V_LENGTH;
    
    uint8_t R,G,B;
    R=(uint8_t)(colorA>>16);
    G=(uint8_t)(colorA>>8);
    B=(uint8_t)(colorA);
    
    pData[7]=R;
    pData[8]=G;
    pData[9]=B;
    
    R=(uint8_t)(colorB>>16);
    G=(uint8_t)(colorB>>8);
    B=(uint8_t)(colorB);
    
    pData[10]=R;
    pData[11]=G;
    pData[12]=B;
    
    
    [self EncryptCode:pData];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=pData[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    pData[len-1]=crc;
    
    if (retData!=NULL) {
        memcpy(retData, pData, len);
    }
   // NSData *data=[[NSData alloc]initWithBytes:pData length:len];
    free(pData);
    
   // return data;
}


+(NSData *) getMoreRGBArray:(NSMutableArray *)array
{
    uint8_t crc=0;
    
    int listsize=(int)array.count;
    
    int len=listsize*3+8;
     uint8_t *byteArray=malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_C;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=(uint8_t) (listsize*3);
    
    uint8_t R,G,B;
    CGFloat Rf,Gf,Bf,Af;
    
    int index=7;
    for (UIColor *color in array) {
        [color getRed:&Rf green:&Gf blue:&Bf alpha:&Af];
        R=(uint8_t)(Rf*255);
        G=(uint8_t)(Gf*255);
        B=(uint8_t)(Bf*255);
        
        byteArray[index++]=R;
        byteArray[index++]=G;
        byteArray[index++]=B;
    }
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int tmp=(int)(crc);
        crc=CRC_TABLE[tmp];
    }
    byteArray[len-1]=crc;
    
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;

}

+(NSData *) getNameCmdArray:(NSString *)name
{
    if(name.length<=0)
    {
        NSLog(@"sendName error =null");
        return NULL;
    }
    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
    NSData *nameStr=[name dataUsingEncoding:enc];
    uint8_t *pbuf=(uint8_t *)nameStr.bytes;
    
    uint8_t crc=0;
    int len=(int)nameStr.length;
    len+=8;
    uint8_t *byteArray=(uint8_t *)malloc(len);
    
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;  //协议版本
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_N;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=(uint8_t) nameStr.length;
    
    for(int i=0;i<nameStr.length;i++)
    {
        byteArray[7+i]=pbuf[i];
    }
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}


#pragma mark 设置密码
+(NSData *) getPassWdCmdArray:(NSString *)passwd
{
    uint8_t crc=0;
    
    int len;
    if(passwd.length>6){
        len=6+8;
    }else{
        len=(int)passwd.length+8;
    }
        uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_P;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=(uint8_t) passwd.length;
    
    NSData *pData=[passwd dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t *pTmp=(uint8_t *)[pData bytes];
    
    for(int i=0;i<len-8;i++)
    {
        byteArray[7+i]=pTmp[i];
    }
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
   
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}

/*
 F命令, 自由变换色
 */
+(NSData *) getTiaoBianArray:(BOOL)enable second:(uint8_t)second
{
    uint8_t crc=0;
    
    int len=2+8;  ///2表示flash是2个字节
        uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_F;
    byteArray[5]= [self getRandomNumber];
    
    byteArray[6]=2;  //flash的字节长度是2
    
    byteArray[7]=enable?0xFF:0x00;
    byteArray[8]=second;
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;

    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    
    return data;
}
#pragma mark 自由渐变颜色
+(NSData *) getJianBianArray:(BOOL)enable second:(uint8_t)second
{
    uint8_t crc=0;
    
    int len=2+8;
       uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_S;
    byteArray[5]= [self getRandomNumber];
    
    byteArray[6]=2;  //flash的字节长度是2
    
    byteArray[7]=enable?0xFF:0x00;
    byteArray[8]=second;
    
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
   
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}
#pragma mark -用户通信前的密码绑定.
+(NSData *) getBondPasswdArray:(NSString *)passwd
{
    uint8_t crc=0;
    
    int len;
    if(passwd.length>6){
        len=6+8;
    }else{
        len=(int)passwd.length+8;
    }
    uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_T;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=(uint8_t) passwd.length;
    
    NSData *pData=[passwd dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t *pTmp=(uint8_t *)[pData bytes];
    
    for(int i=0;i<len-8;i++)
    {
        byteArray[7+i]=pTmp[i];
    }
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
    
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}
#pragma mark -开关灯.
+(NSData *) getOpenLight:(BOOL)isOpen
{
    uint8_t crc=0;
    
    int len;
        len=1+8;
    
    uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_O;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=1;
    
    byteArray[7]=isOpen?1:0;
    
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
    
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}
#pragma mark 发送同步命令
+(NSData *) getSyncBianArray
{
    uint8_t crc=0;
    
    int len;
    len=1+8;
    
    uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_A;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=1;
    byteArray[7]=1;
    
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
    
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}

#pragma mark 一键白光
+(NSData *) getOneKeyWhiteArray
{
    uint8_t crc=0;
    
    int len;
    len=8+8;
    
    uint8_t *byteArray=(uint8_t *)malloc(len);
    byteArray[0]= CMDHEAD1;
    byteArray[1]= CMDHEAD2;
    byteArray[2]=0x01;
    byteArray[3]=CMD_APP_BYTE;
    byteArray[4]= CMD_WORD_W;
    byteArray[5]= [self getRandomNumber];
    byteArray[6]=8;
    
    byteArray[7]=0xFF;
    byteArray[8]=0xFF;
    byteArray[9]=0xFF;
    byteArray[10]=0xFF;
    byteArray[11]=0xFF;
    byteArray[12]=0xFF;
    byteArray[13]=0xFF;
    byteArray[14]=0xFF;
    
    
    [self EncryptCode:byteArray];  //编码
    for(int i=0;i<len-1;i++)
    {
        crc ^=byteArray[i];
        int index=(int)(crc);
        crc=CRC_TABLE[index];
    }
    byteArray[len-1]=crc;
    
    NSData *data=[[NSData alloc]initWithBytes:byteArray length:len];
    free(byteArray);
    
    return data;
}
+(BOOL) checkRcvData:(NSData *)data
{
    int datalen=0;
    int pkglen;
    uint8_t crc=0;
    pkglen=(int)data.length;
    
    uint8_t *byteArray=(uint8_t *)[data bytes];
    if(pkglen>=7)
    {
        datalen=byteArray[6];
        
        if(pkglen==(datalen+8))  //数据长度是正确的.
        {
            for(int i=0;i<pkglen-1;i++)
            {
                crc ^=byteArray[i];
                int index=(int)(crc);
                crc=CRC_TABLE[index];
            }
            if( crc == byteArray[pkglen-1])
                return YES;
            else{
                NSLog(@"checkRcvData: crc check sum rror!");
                return NO;
            }
        }else{
             NSLog(@"checkRcvData: pkglen!=datalen+protocollen,error!");
            return NO;
        }
    }else{
         NSLog(@"checkRcvData: pkglen<7,error!");
        return NO;
    }
}
+(void) EncryptCode:(uint8_t *)byteArray
{
    uint8_t RandomNum=(uint8_t)byteArray[5];
    int len=(uint8_t)byteArray[6];
    int  i;
    //协议从第七个字节开始加密
    for(i=0;i<len;i++)
    {
        byteArray[7+i] ^=RandomNum;
        byteArray[7+i] ^=CRC_TABLE[len];
    }
    return ;
}
+(void)  DecryptCode:(uint8_t *)byteArray
{
    uint8_t RandomNum=byteArray[5];
    int len=(uint8_t)byteArray[6];
    int  i;
    //协议从第七个字节开始加密
    for(i=0;i<len;i++)
    {
        byteArray[7+i] ^=RandomNum;
        byteArray[7+i] ^=CRC_TABLE[len];
    }
    return ;
}

+ (uint8_t)getRandomNumber
{
    int from =1;
    int to=255;
  return (uint8_t)(from + (arc4random() % (to - from + 1)));
}
@end
